package com.icinfo.cloud.provider.common.qr.service.impl;

import cn.hutool.http.HttpStatus;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.icinfo.cloud.provider.common.constant.Constant;
import com.icinfo.cloud.provider.common.dto.FileInfoSaveDto;
import com.icinfo.cloud.provider.common.dto.QrCodeQueryDto;
import com.icinfo.cloud.provider.common.enums.AttachmentRequestContentTypeEnum;
import com.icinfo.cloud.provider.common.enums.FileTransferFormEnum;
import com.icinfo.cloud.provider.common.exception.BusinessException;
import com.icinfo.cloud.provider.common.oss.service.IOssOperateService;
import com.icinfo.cloud.provider.common.qr.service.IQrService;
import com.icinfo.cloud.provider.common.utils.Base64ToMultipartFileUtil;
import com.icinfo.cloud.provider.common.utils.BaseUtil;
import com.icinfo.cloud.provider.common.utils.FileUtil;
import com.icinfo.framework.common.web.Result;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.util.Base64Utils;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Hashtable;

/**
 * @author shishengyao
 * @description
 * @date 2022/3/12
 */
@Service
@Slf4j
public class QrServiceImpl implements IQrService {
    @Resource
    private IOssOperateService iOssOperateService;

    /**
     * 描述：生成二维码
     *
     * @param queryDto {@link QrCodeQueryDto} 二维码查询传输对象
     * @param response {@link HttpServletResponse}
     * @return {@link String }二维码信息
     * @author xiangyuyu
     * @date 2022-03-12 14:06
     */
    @Override
    public String generateQrCode(QrCodeQueryDto queryDto, HttpServletResponse response) {
        String path;
        // 二维码内容
        String text = queryDto.getQrKeyInfo();
        if (ObjectUtils.isEmpty(text)) {
            throw new BusinessException("未指定二维码内容");
        }
        // 二维码图片宽度
        int width = 450;
        // 二维码图片高度
        int height = 450;
        //二维码的图片格式
        String format = "jpg";
        Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();
        // 内容所使用字符集编码
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
        InputStream inputStream = null;
        OutputStream outputStream = null;
        //返回二维码格式类型（1-在线下载地址/2-文件流/3（或缺省）-base64）
        String returnQrInfoType = queryDto.getReturnQrInfoType();
        File des = null;
        try {
            BitMatrix bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, width, height, hints);
            //生成本地图片
            String dir = "qrTmpFiles";
            File fileMkd = new File(dir);
            if (!fileMkd.exists()) {
                fileMkd.mkdirs();
            }
            String uuid = BaseUtil.createUid();
            String fileName = File.separator + uuid + "." + format;
            path = dir + fileName;
            Path pathInfo = Paths.get(path);
            MatrixToImageWriter.writeToPath(bitMatrix, format, pathInfo);
            byte[] bytes = FileUtil.fileToArray(path);
            des = new File(path);
            if (Constant.STRING_1.equalsIgnoreCase(returnQrInfoType)) {
                //上传oss
                FileInfoSaveDto fileInfo = new FileInfoSaveDto();
                fileInfo.setFileBytes(bytes);
                fileInfo.setFileTransferForm(FileTransferFormEnum.FILE_TRANSFER_FORM_3.getCode());
                fileInfo.setFileType(AttachmentRequestContentTypeEnum.jpg.getCode());
                Result result = iOssOperateService.uploadFile(fileInfo);
                if (!ObjectUtils.isEmpty(result)) {
                    Object data = result.getData();
                    if(ObjectUtils.isEmpty(data)){
                        throw new BusinessException("generateQrCode upload file to oss fail-address is null");
                    } else {
                        return data.toString();
                    }
                } else {
                    throw new BusinessException("generateQrCode upload file to oss fail-response is null");
                }
            } else if (Constant.STRING_2.equalsIgnoreCase(returnQrInfoType)) {
                HttpHeaders httpHeaders = new HttpHeaders();
                httpHeaders.setContentType(MediaType.parseMediaType("application/pdf"));
                outputStream = response.getOutputStream();
                //得到输入流
                IOUtils.write(bytes, outputStream);
            } else {
                String base64Info = "data:image/jpg;base64,"+Base64Utils.encodeToString(bytes);
                return base64Info;
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException("二维码生成失败");
        } finally {
            if (Constant.STRING_2.equalsIgnoreCase(returnQrInfoType)) {
                try {
                    inputStream.close();
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (!ObjectUtils.isEmpty(des) && des.exists()) {
                des.delete();
            }
        }
        return null;
    }

    /**
     * 描述： 图片base64转成oss地址
     *
     * @author: zhengqiang
     * @date: 2023/5/22
     * @param: base64String
     * @return {@link String}
     **/
    @Override
    public String base64ToOssUrl(String base64String) {
        try {
            Base64ToMultipartFileUtil fileUtil = new Base64ToMultipartFileUtil(base64String);
            FileInfoSaveDto fileInfo = new FileInfoSaveDto();
            fileInfo.setFileBytes(fileUtil.getBytes());
            fileInfo.setFileTransferForm(FileTransferFormEnum.FILE_TRANSFER_FORM_3.getCode());
            fileInfo.setFileType(AttachmentRequestContentTypeEnum.png.getCode());
            Result result = iOssOperateService.uploadFile(fileInfo);
            if (HttpStatus.HTTP_OK == result.getCode()) {
                return result.getData().toString();
            } else {
                throw new BusinessException("数据处理异常:" + result.getMessage());
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException("数据处理异常");
        }
    }
}
